home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / compress / tar321__.zip / SOURCES.ZIP / STORE.C < prev    next >
C/C++ Source or Header  |  1997-03-14  |  9KB  |  319 lines

  1. /* store.c - storying files into (tape) archive
  2.  * This is the part of the Tar program (see file tar.c)
  3.  * Author: T.V.Shaporev
  4.  * Creation date 14 Dec 1990
  5.  */
  6. #include <stdio.h>
  7.  
  8. #include "sysup.h"
  9. #include "nodedef.h"
  10. #include "modern.h"
  11. #include "define.h"
  12.  
  13. char longname[] = "Tar: name too long: %s\n";
  14.  
  15. #ifdef unix
  16. #    ifdef sun
  17. #        ifndef STDDIR
  18. #            define STDDIR
  19. #        endif
  20. #        include <dirent.h>
  21. #        define    DIRENT struct dirent
  22. #        define    namelen(d) strlen((d)->d_name)
  23. #    endif
  24. #    ifdef i386
  25. #        ifndef STDDIR
  26. #            define STDDIR
  27. #        endif
  28. #        include <dirent.h>
  29. #        define    DIRENT struct dirent
  30. #        define    namelen(d) strlen((d)->d_name)
  31. #    else
  32. #        ifdef M_XENIX
  33. #            ifndef STDDIR
  34. #                define STDDIR
  35. #            endif
  36. #            include <sys/ndir.h>
  37. #            define    DIRENT DIR
  38. #            define    namelen(d) ((d)->d_namlen)
  39. #        endif
  40. #    endif
  41. #endif
  42. #ifdef UNIX
  43. #    ifndef STDDIR
  44. #        include <sys/dir.h>
  45. #    endif
  46. #endif
  47.  
  48. #ifdef MSDOS
  49. #    include <string.h>
  50. #else
  51.     int  strlen();
  52.     char *strcpy(), *strcat(), *strncpy();
  53.     int  open(), read(), close();
  54. #    ifdef RMKDIR
  55.         int rmdir();
  56. #    endif
  57.     long lseek();
  58. #endif
  59.  
  60. #define dotname(n) ((n)[0]=='.' && ((n)[1]=='\0'||((n)[1]=='.'&&(n)[2]=='\0')))
  61.  
  62. void proctl  __ARGS__(( char *, long ));
  63. void procts  __ARGS__(( char *, short, char ));
  64. void prcsum  __ARGS__(( register header * ));
  65. void newhead __ARGS__(( char *, long ));
  66. char *deleft __ARGS__(( char * ));
  67.  
  68. void nullblock(h)
  69. header *h;
  70. {
  71.    register i; for (i=0; i<BLKSIZE/sizeof(int); i++) *((int*)h + i) = 0;
  72. }
  73.  
  74. void proctl(dest, l)
  75. char dest[]; long l;
  76. {
  77.    register int i;
  78.  
  79.    dest[i = 11] = ' ';
  80.    do dest[--i] = ((char)l & 7) | '0'; while (i>0 && (l>>=3)!=0);
  81.    while (i>0) dest[--i] = ' ';
  82. }
  83.  
  84. void procts(dest, s, suffix)
  85. char dest[]; short s; char suffix;
  86. {
  87.    register int i;
  88.  
  89.    dest[7] = 0;
  90.    dest[i = 6] = suffix;
  91.    do dest[--i] = (s & 7) | '0'; while (i>0 && (s>>=3)!=0);
  92.    while (i>0) dest[--i] = ' ';
  93. }
  94.  
  95. void prcsum(h)
  96. register header *h;
  97. {
  98.    register i;
  99.    /* for the sake of compatibility */
  100.    for (i=0; i<8; i++) (h->m.chksum)[i] = ' ';
  101.    procts(h->m.chksum, headsum(h), 0);
  102. }
  103.  
  104. void newhead(filename, filesize)
  105. char *filename;
  106. long filesize;
  107. {
  108.    nullblock(hblock = steptape());
  109.    procts(hblock->m.mode,  (short)st.st_mode & 07777, ' ');
  110.    procts(hblock->m.uid,   (short)st.st_uid, ' ');
  111.    procts(hblock->m.gid,   (short)st.st_gid, ' ');
  112.    proctl(hblock->m.size,  filesize);
  113.    proctl(hblock->m.mtime, st.st_mtime);
  114.    (void)strncpy(hblock->m.name, filename, MAXTNAME);
  115. }
  116.  
  117. char *deleft(p)
  118. register char *p;
  119. {
  120. #ifdef MSDOS
  121.    if (deldrv && p[1] == ':' &&
  122.                 (p[0]>='A' && p[0]<='Z' || p[0]>='a' && p[0]<='z'))
  123.       p += 2;
  124. #endif
  125.    if (dslash && *p == '/') ++p;
  126.    return p;
  127. }
  128.  
  129. void store(fname)
  130. char *fname;
  131. {
  132.    static level = 0;
  133.    register i; register j;
  134.    register unsigned m;
  135.    register char *p;
  136. #ifdef UNIX
  137. #  ifdef STDDIR
  138.       register DIR *d0; register DIRENT *dp;
  139. #  else
  140.       register char *q; struct direct d_buf; int infile;
  141. #  endif
  142. #endif
  143. #ifdef MSDOS
  144.    register k;
  145.    register c, n;
  146.    lcwdent_t e;
  147.    static char misdir[] = "Tar: can\'t chdir to %s\n";
  148.    static char misret[] = "Tar: can\'t return to %s\n";
  149. #endif
  150.    if (cbreak) done(EXIT); ++level;
  151. #ifdef MSDOS
  152.    p = fname + (n = fnoffset(fname));
  153.    if (n >= MAXTNAME && !nonest) {
  154.       (void)fprintf(myout, longname, fname);
  155.       goto end;
  156.    }
  157.    if (level<2 && n) { /* there is drive:directory in the name */
  158.       c = *p; *p = '\0'; /* cut off file name */
  159.       k = cwd(fname);
  160.       *p = c; /* restore */
  161.       if (k) {
  162.          (void)fprintf(stderr, misdir, fname);
  163.          goto end;
  164.       }
  165.    }
  166.    if (!*p || (*p=='.' && !*(p+1))) {
  167.       /* No file spec, just directory prefix */
  168.       (void)strcpy(p, "*.*"); store(fname); goto end;
  169.    }
  170.    k = lfindfirst(&e, p, filemask);
  171.    for (i=0; !k && dotname(e.filenameP); i++) k = lfindnext(&e);
  172.    if (k) {
  173.       if (level < 2) (void)fprintf(myout,"Tar: can\'t find \'%s\'\n",fname);
  174.       if (i) lfindend(&e);
  175.       goto end;
  176.    }
  177.    do {
  178.       if ((i = strlen(e.filenameP)) > MAXTNAME ||
  179.          (!nonest && strlen(fname) + i >= MAXTNAME)) {
  180.          (void)fprintf(myout,"Tar: name too long: %s\\%s\n",
  181.             fname, e.filenameP);
  182.          continue;
  183.       }
  184.       (void)strcpy(p, e.filenameP);
  185. #else
  186.       if (!nonest && strlen(fname) > MAXTNAME) {
  187.          (void)fprintf(myout, longname, fname);
  188.          goto end;
  189.       }
  190. #endif
  191.       for (i=0; i<xcnt; i++) {
  192.          if (fmatch(xarg[i], fname)) goto end;
  193.       }
  194. #ifdef MSDOS
  195.       fcb2stat(&st, e.unopened_fcbP);
  196. #else
  197.       if (stat(fname, &st) < 0) {
  198.          (void)fprintf(myout, "Tar: can\'t handle \'%s\'\n", fname);
  199.          goto end;
  200.       }
  201. #endif
  202.       if ((m = st.st_mode & S_IFMT) == S_IFDIR) {
  203.          if (nonest && level > 1) goto end;
  204. #ifdef UNIX
  205.          if (p_flag) {/* save directory & permissions */
  206.             newhead((p = deleft(fname)), 0L);
  207.             if ((j = strlen(p)) < MAXTNAME-1) {
  208.                hblock->m.name[j+1] = '\0';
  209.             } else {
  210.                j = MAXTNAME-1;
  211.             }
  212.             hblock->m.name[j] = '/';
  213.             prcsum(hblock);
  214.          }
  215. #  ifdef STDDIR
  216.          if ((d0 = opendir(fname)) == NULL) {
  217.             (void)fprintf(myout, "Tar: can\'t open directory \'%s\'\n", fname);
  218.             goto end;
  219.          }
  220.          fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
  221.  
  222.          for (dp=readdir(d0); dp; dp=readdir(d0)) {
  223.             j = namelen(dp);
  224.             if (j==0 ||
  225.                (j==1 && (dp->d_name)[0]=='.') ||
  226.                (j==2 && (dp->d_name)[0]=='.' && (dp->d_name[1])=='.'))
  227.                continue;
  228.             for (i=0; i<j; i++) p[i] = (dp->d_name)[i];
  229.             p[j] = 0;
  230.             store(fname);
  231.          }
  232.          closedir(d0);
  233. #  else
  234.          if ((infile = open(fname, O_RDONLY)) < 0) {
  235.             (void)fprintf(myout, "Tar: can\'t open file \'%s\'\n", fname);
  236.             goto end;
  237.          }
  238.          fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
  239.  
  240.          i = 0;
  241.          while (read(infile, (char*)&d_buf, sizeof(d_buf)) > 0 && !cbreak) {
  242.             if (d_buf.d_ino!=0 && !dotname(d_buf.d_name)) {
  243.                q = p;
  244.                for (j=0; j<DIRSIZ; j++) *q++ = d_buf.d_name[j];
  245.                *q = '\0';
  246.                (void)close(infile); /* need this file handler */
  247.                store(fname);
  248.                *p = '\0';
  249.                infile = open(fname, O_RDONLY);
  250.                (void)lseek(infile, (long)(sizeof(d_buf) * (i+1)), 0);
  251.             }
  252.             ++i;
  253.          }
  254. #  endif
  255.          if (y_flag) {
  256. #        ifdef RMKDIR
  257.                if (rmdir(fname) != 0) {
  258.                   (void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
  259.                }
  260. #        else
  261.                if (bincall("rmdir", fname) == -1) {
  262.                   (void)fprintf(myout, "Tar: fault run rmdir!\n");
  263.                }
  264. #        endif
  265.          }
  266. #endif
  267. #ifdef MSDOS
  268.          j = strlen(fname);
  269.          strcpy(fname+j, "/*.*");
  270.          if (chdir(e.filenameP)) {
  271.              fprintf(myout, misdir, fname);
  272.          } else {
  273.              store(fname);
  274.              fname[j] = '\0';
  275.              if (chdir("..")) {
  276.                  fprintf(myout, misret, fname);
  277.                  done(ERINIT);
  278.              }
  279.              if (y_flag) {
  280.                 if (rmdir(fname) != 0)
  281.                    (void)fprintf(myout,"Tar: can\'t remove \'%s\'\n",
  282.                       fname);
  283.              }
  284.          }
  285. #endif
  286.       } else if (m == S_IFREG) {
  287.          savefile(fname);
  288.       } else {
  289. #ifdef UNIX
  290.          p = deleft(fname);
  291.          if (w_flag && !okwork('a', ' ', &st, fname)) goto end;
  292.          if (v_flag) (void)fprintf(myout, "a %s\n", p);
  293.          if (m == S_IFCHR || m == S_IFBLK || m == S_IFIFO) {
  294.             newhead(p, 0L);
  295.             if (m == S_IFIFO) {
  296.                hblock->m.filetype = TF_QUE;
  297.             } else {
  298.                hblock->m.filetype = m == S_IFBLK ? TF_BLK : TF_CHR;
  299.                procts(hblock->x.devmajor, major(st.st_rdev), ' ');
  300.                procts(hblock->x.devminor, minor(st.st_rdev), ' ');
  301.             }
  302.             prcsum(hblock);
  303.          } else
  304. #endif
  305.             (void)fprintf(myout, "Tar: \'%s\' not a file\n", fname);
  306.       }
  307. #ifdef MSDOS
  308.    } while (0 == (k = lfindnext(&e)));
  309.    (void)lfindend(&e);
  310. #endif
  311. end: --level;
  312. #ifdef MSDOS
  313.    if (!level && cwd(startdir)) {
  314.       (void)fprintf(myout, misret, startdir);
  315.       done(ERINIT);
  316.    }
  317. #endif
  318. }
  319.